/*
 *	ME2 C++ SDK
 *	Copyright (c) 2010 _silencer
 *
 *	Permission is hereby granted, free of charge, to any person
 *	obtaining a copy of this software and associated documentation
 *	files (the "Software"), to deal in the Software without
 *	restriction, including without limitation the rights to use,
 *	copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the
 *	Software is furnished to do so, subject to the following
 *	conditions:
 *
 *	The above copyright notice and this permission notice shall be
 *	included in all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *	OTHER DEALINGS IN THE SOFTWARE.
 */

#include "stdafx.h"
#include "generator_mod.h"

uengine_interface& engine_interface( uengine_interface::get_singleton() );
boost::shared_ptr<generator_mod> generator_mod_ptr;

void start_mod()
{
	/* Attach to console of launcher so we can show some information */
	AttachConsole( ATTACH_PARENT_PROCESS );

	*stdout = *_tfdopen( _open_osfhandle( (intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY ), _T("a") ); 
	*stderr = *_tfdopen( _open_osfhandle( (intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_WRONLY ), _T("a") ); 
	*stdin = *_tfdopen( _open_osfhandle( (intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_WRONLY ), _T("r") ); 

	/* Now setup the sdk and get our mod running */
	std::cout << "generator_mod starting..." << std::endl;

	engine_interface.initialize_interface();

	if ( engine_interface.is_initialized() )
		generator_mod_ptr.reset( new generator_mod() );
}

void stop_mod()
{
	std::cout << "generator_mod stopping..." << std::endl;

	if ( generator_mod_ptr )
		generator_mod_ptr.reset();

	engine_interface.cleanup_interface();
}

generator_mod::~generator_mod()
{
	/* Sort all the classes (on dependencies) */
	collector_.sort();

	/* Generate C++ wrapper for the game engine classes */
	unative_sdk_generator generator( collector_ );

	std::ofstream global( "C:\\me2_sdk\\unreal_game_global.h", std::ios::binary );

	if ( global.good() )
	{
		generator.build_global_header( global );
		global.close();
	}

	unreal::usdk_package_list& packages( collector_.get_packages() );
	unreal::usdk_package_list_iterator package( packages.begin() );

	for ( ; package != packages.end(); ++package )
	{
		std::string header_filename( "C:\\me2_sdk\\unreal_game_" );
		header_filename += (*package).first;
		header_filename += ".h";

		std::string code_filename( "C:\\me2_sdk\\unreal_game_" );
		code_filename += (*package).first;
		code_filename += ".cpp";

		std::ofstream header( header_filename.c_str(), std::ios::binary );

		if ( header.good() )
		{
			generator.build_header( header, (*package).first );
			header.close();
		}

		std::ofstream code( code_filename.c_str(), std::ios::binary );

		if ( code.good() )
		{
			generator.build_implementation( code, (*package).first );
			code.close();
		}
	}
}

void generator_mod::on_tick( float delta_time )
{
	static float time( 0 );
	
	/* Collect engine classes after some time */
	time += delta_time;

	if ( time > 25 )
	{
		/* TODO process a small range of objects per time slice (to make it run more transparent and not stall engine) */
		collector_.process_all();
		time = 0;
	}
}
